package com.wolfking.converter.transform.extend;

import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.wolfking.converter.exception.MoreTransformException;
import com.wolfking.converter.transform.AbstractExtendTransform;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Objects;

@Slf4j
public class MoreTransform extends AbstractExtendTransform<Object> {


    private List<TransformConfig> transformConfigList;


    public MoreTransform() {

    }

    public MoreTransform(String config) {
        transformConfigList = Lists.newArrayList();
        JsonElement element = JsonParser.parseString(config);
        if (element.isJsonArray()) {
            JsonArray array = element.getAsJsonArray();
            for (int i = 0; i < array.size(); i++) {
                JsonObject object = array.get(i).getAsJsonObject();
                String classname = object.get("classname").getAsString();
                String constructArg = object.has("constructArg") ? object.get("constructArg").toString() : null;
                transformConfigList.add(new TransformConfig(classname, constructArg));
            }
        }
    }

    @Override
    public Object transform(Object value) throws Exception {
        if (Objects.isNull(value) || (value instanceof String && StringUtils.isBlank(value.toString()))) {
            return value;
        }
        Object returnObj = value;
        int size = transformConfigList.size();
        try {
            for (int i = 0; i < size; i++) {
                TransformConfig transformConfig = transformConfigList.get(i);
                AbstractExtendTransform<?> extendTransform;
                if (StringUtils.isNotBlank(transformConfig.getConstructArg())) {
                    extendTransform = (AbstractExtendTransform<?>) Class.forName(transformConfig.getClassname()).getDeclaredConstructor(String.class).newInstance(transformConfig.constructArg);
                } else {
                    extendTransform = (AbstractExtendTransform<?>) Class.forName(transformConfig.getClassname()).newInstance();
                }

                Object transform = extendTransform.transform(returnObj);
                log.info("第{}个转换器{}，输入 {}，输出{}", i + 1, transformConfig.getClassname(), returnObj, transform);
                if (Objects.isNull(transform)) {
                    throw new MoreTransformException(String.format("第%s个转换器，返回空对象,\n输入参数是%s,\n类名是%s，\n构造参数是%s", i, returnObj, transformConfig.getClassname(), transformConfig.getConstructArg()), null);
                }
                returnObj = transform;
            }
            log.info("more transform {} return obj is {}", value, returnObj);
            return returnObj;
        } catch (Exception e) {
            throw new MoreTransformException("转换失败", e);
        }
    }

    @Data
    @AllArgsConstructor
    private static class TransformConfig {
        private String classname;
        private String constructArg;
    }


    @Override
    public String getExampleConfig() {
        return "[{\n" +
                "\t\"classname\": \"com.wolfking.converter.transform.extend.SqlQueryTransform\",\n" +
                "\t\"constructArg\": {\n" +
                "\n" +
                "\t}\n" +
                "}, {\n" +
                "\t\"classname\": \"com.wolfking.converter.transform.extend.SqlQueryTransform\",\n" +
                "\t\"constructArg\": {\n" +
                "\n" +
                "\t}\n" +
                "}]";
    }

    @Override
    public String getExampleConfigDesc() {
        return "classname是类名，constructArg是参数，可以是json对象，json数组，字符串，也可以为空";
    }
}